package cn.hy.face.module.sync.utils;

import org.springframework.util.CollectionUtils;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 同步utils
 */
public class SyncUtils {

    /**
     * 私钥
     */
    public static final String APP_SECRET = "7IjPiuA8v1GY1VJQJJSIWdNi5YeUdZ0I";

    /**
     * 验证签名
     * @return
     */
    public static boolean checkSign(HttpServletRequest request, String sign) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (CollectionUtils.isEmpty(parameterMap)) {
            return false;
        }
        Map<String, String> paramMap = new HashMap<>(12);

        Set<String> paramKeys = parameterMap.keySet();
        for (String strTmp : paramKeys) {
            if ("sign".equals(strTmp)) {
                continue;
            }
            String[] paramTmp = parameterMap.get(strTmp);
            paramMap.put(strTmp, strArrayToStr(paramTmp));
        }

        String localSign = sign(APP_SECRET, paramMap);
        return localSign != null && localSign.equals(sign);
    }

    /**
     * 获取签名信息
     * @param secretKey appSecret
     * @param params 请求参数（无需排序，本方法自动排序）
     * @return
     */
    public static String sign(String secretKey,Map<String,String> params){
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        StringBuilder query = new StringBuilder();
        query.append(secretKey);
        for (String key : keys) {
            String value = params.get(key);
            if (key!=null&&!"".equals(key.trim()) && value!=null&&!"".equals(value.trim())) {
                query.append(key).append(value);
            }
        }
        query.append(secretKey);
        byte[] bytes = null;
        try {
            bytes = encryptHMAC(query.toString(), secretKey);
        }catch(IOException e){
            return null;
        }
        return byte2hex(bytes);
    }

    /**
     * 把字节流转换为十六进制表示方式。
     */
    private static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }

    private static byte[] encryptHMAC(String data, String secret) throws IOException {
        byte[] bytes = null;
        try {
            SecretKey secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacMD5");
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            bytes = mac.doFinal(data.getBytes("UTF-8"));
        } catch (GeneralSecurityException gse) {
            throw new IOException(gse.toString());
        }
        return bytes;
    }

    public static String strArrayToStr(String[] strs) {
        if (null == strs || strs.length == 0) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String strTmp : strs) {
            stringBuilder.append(strTmp);
        }
        return stringBuilder.toString();
    }


    /**
     * 格式化上次同步时间
     * @return
     */
    public static long formatPreSyncTime(long preSyncTime) {
        return preSyncTime - 1000;
    }
}
